import enum
from sls_controller.sls_missionsABC import Missions, MissionsState
from sls_controller.sls_missionsFactory import MissionsFactory

import json

class MisssionsScheduleState(enum.Enum):
    STOP = 0
    RUNNING = 1
    SUSPEND = 2
    ERROR = 3

# class ComplexMissionsScheduleState(enum.Enum):
#     STOP = 0
#     RUNNING = 1
#     SUSPEND = 2
#     ERROR = 3
class MissionsSchedule():
    # 添加类变量来存储单例实例
    _instance = None
    
    def __new__(cls,*args, **kwargs):
        # 如果实例不存在则创建新实例
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self,missionsFactory:MissionsFactory):
        # 防止重复初始化
        if not hasattr(self, '_initialized'):
            self.__state = MisssionsScheduleState.STOP
            self.__missionsList:list[Missions] = []
            self.__missionsIndex = 0
            self._initialized = True
            self.__missionsIndex_last = None
            self.missionsFactory = missionsFactory
            self.schedule_taskfinish_callback = None
            self.schedule_taskabort_callback = None
            self.runingTask_changed_callback = None

    def append_mission(self,missions:Missions):
        self.__missionsList.append(missions)

    def append_missions_from_list(self,missionsList:list[Missions]):
        for missions in missionsList:
            self.append_mission(self.missionsFactory.create_missions_from_type(missions["missionsType"],missions["datasets"]))
        print(f"append {len(self.__missionsList)} missions")

    def append_missions_from_json(self,missionsJson:str):
        missionsList = json.loads(missionsJson)
        for missions in missionsList:
            self.append_mission(self.missionsFactory.create_missions_from_type(missions["missionsType"],missions["datasets"]))
        print(f"append {len(self.__missionsList)} missions")

    def append_mission_from_json(self,missionJson:str):
        missionDict = json.loads(missionJson)
        self.append_mission(self.missionsFactory.create_missions_from_type(missionDict["missionsType"],missionDict["datasets"]))

    def append_mission_from_dict(self,missionDict:dict):
        self.append_mission(self.missionsFactory.create_missions_from_type(missionDict["missionsType"],missionDict["datasets"]))
    
    def add_mission_from_dict(self, missionDict: dict, index: int):
        self.__missionsList.insert(index, self.missionsFactory.create_missions_from_type(missionDict["missionsType"],missionDict["datasets"]))

    def moveup_mission_from_index(self,index:int):
        if index > 0:
            self.__missionsList.insert(index-1, self.__missionsList.pop(index))
    
    def movedown_mission_from_index(self,index:int):
        if index < len(self.__missionsList)-1:
            self.__missionsList.insert(index+1, self.__missionsList.pop(index))
            
    def delete_mission_from_index(self,index:int):
        self.__missionsList.pop(index)

    def read_missions_detail_as_list(self) -> str:
        missionsDetail =[]
        for i in range(len(self.__missionsList)):
            missionsDetail.append({"missionsType":self.__missionsList[i].__class__.__name__,"datasets":self.__missionsList[i].datasets})
        return missionsDetail
    def read_mission_data_from_index(self,index:int) -> dict:
        return self.__missionsList[index].datasets

    def read_mission_name_from_index(self, index: int) -> str:
        return self.__missionsList[index].__class__.__name__
    
    def read_schedule_stateAndIndex(self) -> dict:
        if self.__state == MisssionsScheduleState.RUNNING:
            return {"state":"运行","index":self.__missionsIndex}
        elif self.__state == MisssionsScheduleState.SUSPEND:
            return {"state":"暂停","index":self.__missionsIndex}
        elif self.__state == MisssionsScheduleState.STOP:
            return {"state":"停止","index":self.__missionsIndex}

    def startMissions(self):
        self.__state = MisssionsScheduleState.RUNNING
        print(f"start missions")

    def restartMissions(self):
        if self.__state == MisssionsScheduleState.STOP:
            self.__missionsIndex = 0
            self.__missionsIndex_last = None
            missionsList = self.read_missions_detail_as_list()
            self.__missionsList.clear()
            for mission in missionsList:
                self.__missionsList.append(self.missionsFactory.create_missions_from_type(mission["missionsType"],mission["datasets"]))
            self.__state = MisssionsScheduleState.RUNNING

    def stopMissions(self):
        self.__state = MisssionsScheduleState.STOP
        #保护动作
        #need to do 

    def suspendMissions(self):
        self.__state = MisssionsScheduleState.SUSPEND
    
    def set_schedule_taskfinish_callback(self,callback):
        self.schedule_taskfinish_callback = callback
    
    def set_schedule_taskabort_callback(self,callback):
        self.schedule_taskabort_callback = callback

    def set_runingTask_changed_callback(self,callback):
        self.runingTask_changed_callback= callback
        

    def schedule_task(self):
        if self.__state == MisssionsScheduleState.RUNNING:
            #print(f"mission {self.__missionsIndex}")
            if self.__missionsIndex < len(self.__missionsList):
                #判断missionIndex相对上一个循环有没有改变，如果改变了则调用runingTask_changed_callback
                if self.__missionsIndex == 0 and self.__missionsIndex_last == None:
                    if self.runingTask_changed_callback!= None:
                        self.runingTask_changed_callback(self.__missionsIndex)
                    self.__missionsIndex_last = self.__missionsIndex
                    print(f"mission {self.__missionsIndex}")
                elif self.__missionsIndex != self.__missionsIndex_last:
                    if self.runingTask_changed_callback != None:
                        self.runingTask_changed_callback(self.__missionsIndex)
                    self.__missionsIndex_last = self.__missionsIndex
                    print(f"mission {self.__missionsIndex}")
                #开始执行mission的循环
                missionHandle = self.__missionsList[self.__missionsIndex]
            # missions start to run
                if missionHandle.state  == MissionsState.WAITING:
                    if missionHandle.fore_check():
                        missionHandle.state = MissionsState.RUNNING
                        missionHandle.mission_enter()
                    if missionHandle.positive_abort_check():
                        missionHandle.mission_abort()
                        missionHandle.state = MissionsState.ABORT
                elif missionHandle.state == MissionsState.RUNNING:
                    missionHandle.mission_action()
                    if missionHandle.done_check():
                        missionHandle.state = MissionsState.DONE
                        missionHandle.mission_exit()
                    if missionHandle.abort_check() or missionHandle.positive_abort_check():
                        missionHandle.mission_abort()
                        missionHandle.state = MissionsState.ABORT                        
                elif missionHandle.state == MissionsState.DONE:
                    #a finish_callback function is called
                    if missionHandle.finish_callback != None:
                        missionHandle.finish_callback()
                    if self.schedule_taskfinish_callback != None:
                        self.schedule_taskfinish_callback(self.__missionsIndex)
                    self.__missionsIndex += 1
                elif missionHandle.state == MissionsState.ABORT:
                    #a abort_callback function is called
                    if missionHandle.abort_callback != None:
                        missionHandle.abort_callback()
                    if self.schedule_taskabort_callback != None:
                        self.schedule_taskabort_callback(self.__missionsIndex)
                    self.__missionsIndex += 1

# class ComplexMissionsSchedule():
#     # 添加类变量来存储单例实例
#     _instance = None
    
#     def __new__(cls,*args, **kwargs):
#         # 如果实例不存在则创建新实例
#         if cls._instance is None:
#             cls._instance = super().__new__(cls)
#         return cls._instance

#     def __init__(self,publicResource):
#         # 防止重复初始化
#         if not hasattr(self, '_initialized'):
#             self.__state = ComplexMissionsScheduleState.STOP
#             self.__complexMissionsList:list = []
#             self.__complexMissionsIndex = 0
#             self.publicResourceList = publicResource
#             self._initialized = True

#     def append_complexMissions(self,complexMissions:ComplexMissions):
#         self.__complexMissionsList.append(complexMissions)

#     def startComplexMissions(self):
#         self.__state = ComplexMissionsScheduleState.RUNNING

#     def stopCompolexMissions(self):
#         self.__state = ComplexMissionsScheduleState.STOP
    
#     def schedule_task(self):
#         if self.__state == ComplexMissionsScheduleState.RUNNING:
#             if self.__complexMissionsIndex < len(self.__complexMissionsList):    
#                 complexMissionHandle:ComplexMissions = self.__complexMissionsList[self.__complexMissionsIndex]
#                 # missions schedule
#                 if complexMissionHandle.missionsIndex < len(complexMissionHandle.missionsList):
#                     missionHandle = complexMissionHandle.missionsList[complexMissionHandle.missionsIndex]
#                     if missionHandle.state  == MissionsState.WAITING:
#                         if missionHandle.fore_check():
#                             missionHandle.state = MissionsState.RUNNING
#                             missionHandle.mission_enter()
#                             print(f"run the complexMission {self.__complexMissionsIndex} and mission{complexMissionHandle.missionsIndex}")
#                     elif missionHandle.state == MissionsState.RUNNING:
#                         missionHandle.mission_action()
#                         if missionHandle.done_check():
#                             missionHandle.state = MissionsState.DONE
#                             missionHandle.mission_exit()
#                         if missionHandle.abort_check() or missionHandle.positive_abort_check():
#                             missionHandle.state = MissionsState.ABORT
#                             missionHandle.mission_abort()
#                     elif missionHandle.state == MissionsState.DONE:
#                         #can notify one of missions done
#                         complexMissionHandle.missionsIndex += 1
#                     elif missionHandle.state == MissionsState.ABORT:
#                         #can notify one of missions abort
#                         complexMissionHandle.missionMidFailedFlag = True
#                         complexMissionHandle.missionsIndex += 1
#                 else:
#                     #finished should notify 
#                     complexMissionHandle.missionFinishedFlag = True
#                     pass
  
#                 # service missions schedule
#                 serviceMissionHandle = complexMissionHandle.serviceMissions
#                 if  serviceMissionHandle != None and complexMissionHandle.serviceMissionsFinishedFlag != True and complexMissionHandle.missionMidFailedFlag != True:
#                     if serviceMissionHandle.state  == MissionsState.WAITING:
#                         if serviceMissionHandle.fore_check():
#                             serviceMissionHandle.state = MissionsState.RUNNING
#                             serviceMissionHandle.mission_enter()
#                     elif serviceMissionHandle.state == MissionsState.RUNNING:
#                         serviceMissionHandle.mission_action()
#                         if serviceMissionHandle.done_check():
#                             serviceMissionHandle.state = MissionsState.DONE
#                             serviceMissionHandle.mission_exit()
#                         if serviceMissionHandle.abort_check() or serviceMissionHandle.positive_abort_check():
#                             serviceMissionHandle.state = MissionsState.ABORT
#                             serviceMissionHandle.mission_abort()
#                     elif  serviceMissionHandle.state == MissionsState.DONE:
#                         complexMissionHandle.serviceMissionsFinishedFlag = True
#                         #finished should notify
#                         pass
#                     elif serviceMissionHandle.state == MissionsState.ABORT:
#                         complexMissionHandle.serviceMissionsFalidFlag = True
#                         #finished should notify
#                         pass
#                 else:
#                     #finished should notify
#                     pass
#                 # abort notify system to do!!!!!
#                 if complexMissionHandle.missionMidFailedFlag == True:
#                     #to do !!!!!
#                     pass
#                 if complexMissionHandle.serviceMissionsFalidFlag == True:
#                     #to do !!!!!
#                     pass
#                 # base on the mission or service mission youxian decide the complexmission is ended   
#                 if complexMissionHandle.missionPriority == 0:
#                     if complexMissionHandle.missionFinishedFlag == True:
#                         #终端当前的伴随任务：
#                         if serviceMissionHandle != None:
#                             serviceMissionHandle.state = MissionsState.ABORT
#                             serviceMissionHandle.mission_abort()
#                         #移动到下-个复杂任务
#                         print(f"finished the complexMission {self.__complexMissionsIndex}") 
#                         self.__complexMissionsIndex += 1
#                 else:
#                     if complexMissionHandle.serviceMissionsFinishedFlag == True:
#                         #中断当前的飞行任务：
#                         missionHandle.state = MissionsState.ABORT
#                         missionHandle.mission_abort()
#                         #移动到下一个复杂任务
#                         print(f"finished the complexMission {self.__complexMissionsIndex}") 
#                         self.__complexMissionsIndex += 1
                

    